package net.stogi.dsper.ui.client.module.tag;

import java.util.ArrayList;
import java.util.List;

import net.stogi.common.mvp.core.behavior.Behavior;

import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FormButtonBinding;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.extjs.gxt.ui.client.widget.layout.HBoxLayout;
import com.extjs.gxt.ui.client.widget.layout.HBoxLayoutData;

class TagEditorWidget extends Composite implements TagEditorView {

	private static final HBoxLayoutData DEFAULT_TAG_FIELD_LAYOUT_DATA = new HBoxLayoutData(new Margins(2, 20, 0, 2));

	private final Button addButton = new Button();

	private final Button cancelButton = new Button();

	private LayoutContainer lastRowLayoutContainer;

	private final FormPanel mainPanel = new FormPanel();

	private final FormButtonBinding mainPanelButtonBinding = new FormButtonBinding(mainPanel);

	private final List<TextField<String>> newTagTextFieldList = new ArrayList<TextField<String>>();

	private final Button saveButton = new Button();

	private final List<TextField<String>> savedTagTextFieldList = new ArrayList<TextField<String>>();

	public TagEditorWidget() {
		initBinding();
		initComposite();
		initLayout();
		initComponent(mainPanel);
	}

	@Override
	public void addTag() {
		doAddNewTagTextField();
		mainPanel.layout();
	}

	@Override
	public void appear() {
		mainPanel.show();
		// mainPanel.el().fadeIn(FxConfig.NONE);
	}

	@Override
	public void block() {
		mainPanel.setEnabled(false);
	}

	@Override
	public List<String> collectTags() {
		List<String> tagList = new ArrayList<String>();
		for (TextField<String> tagTextField : newTagTextFieldList) {
			String value = tagTextField.getValue();
			if (value != null) {
				tagList.add(value);
			}
		}
		newTagTextFieldList.clear();
		lastRowLayoutContainer = null;
		return tagList;
	}

	@Override
	public void disappear() {
		// mainPanel.el().fadeOut(FxConfig.NONE);
		mainPanel.hide();
		doCleanTagEditor();
	}

	@Override
	public void displayTags(List<String> tagList) {
		if (mainPanel.removeAll()) {
			for (String tag : tagList) {
				doAddSavedTagTextField(tag);
			}
			mainPanel.layout();
		}
	}

	@Override
	public void setAddBehavior(final Behavior behavior) {
		addButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				behavior.behave();
			}
		});
	}

	@Override
	public void setCancelBehavior(final Behavior behavior) {
		cancelButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				behavior.behave();
			}
		});
	}

	@Override
	public void setSaveBehavior(final Behavior behavior) {
		saveButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				behavior.behave();
			}
		});
	}

	@Override
	public void unblock() {
		mainPanel.setEnabled(true);
	}

	private void doAddNewTagTextField() {
		TextField<String> tagTextField = new TextField<String>();
		doInitTagTextField(tagTextField);
		newTagTextFieldList.add(tagTextField);
		doAddTagTextFieldToMainPanel(tagTextField);
	}

	private void doAddSavedTagTextField(String value) {
		if (value == null) {
			throw new IllegalArgumentException("Parameter 'value' can not be null");
		}
		TextField<String> tagTextField = new TextField<String>();
		doInitTagTextField(tagTextField);
		tagTextField.setEnabled(false);
		tagTextField.setValue(value);
		savedTagTextFieldList.add(tagTextField);
		doAddTagTextFieldToMainPanel(tagTextField);
	}

	private void doAddTagTextFieldToMainPanel(TextField<String> tagTextField) {
		if (lastRowLayoutContainer == null || (savedTagTextFieldList.size() + newTagTextFieldList.size() - 1) % 3 == 0) {
			HBoxLayout rowLayout = new HBoxLayout();
			lastRowLayoutContainer = new LayoutContainer(rowLayout);
			mainPanel.add(lastRowLayoutContainer);
			lastRowLayoutContainer.add(tagTextField, DEFAULT_TAG_FIELD_LAYOUT_DATA);
		}
		else {
			lastRowLayoutContainer.add(tagTextField, DEFAULT_TAG_FIELD_LAYOUT_DATA);
		}
	}

	private void doInitTagTextField(TextField<String> tagTextField) {
		if (tagTextField == null) {
			throw new IllegalArgumentException("Parameter 'tagTextField' can not be null");
		}
		tagTextField.setWidth(180);
		tagTextField.setRegex("(\\w)*");
		tagTextField.getMessages().setRegexText("Provide only one word");
	}

	private void doCleanTagEditor() {
		mainPanel.clear();
		newTagTextFieldList.clear();
		savedTagTextFieldList.clear();
		lastRowLayoutContainer = null;
	}

	private void initBinding() {
		mainPanelButtonBinding.addButton(saveButton);
	}

	private void initComposite() {
		addButton.setText("Add");
		cancelButton.setText("Cancel");
		saveButton.setText("Save");

		mainPanel.setHeading("Tag Editor");
		mainPanel.setFrame(true);
		mainPanel.setHeight(0);
		mainPanel.setLayout(new FlowLayout());
		mainPanel.setPadding(0);
		mainPanel.setWidth(620);
		mainPanel.setVisible(false);
	}

	private void initLayout() {
		mainPanel.addButton(addButton);
		mainPanel.addButton(cancelButton);
		mainPanel.addButton(saveButton);
	}
}
